package com.schematic.flixel.donquicoco
{
import com.schematic.flixel.Controller;
import com.schematic.flixel.Utils;

import flash.geom.Point;

import flashx.textLayout.formats.Direction;

import org.flixel.FlxG;
import org.flixel.FlxGroup;
import org.flixel.FlxPoint;
import org.flixel.FlxSound;
import org.flixel.FlxSprite;
import org.flixel.FlxState;
import org.flixel.FlxText;
import org.flixel.FlxTilemap;
import org.flixel.FlxU;




public class DonquiCocoGame extends FlxState
{

    //--------------------------------------------------------------------------
    //
    //  Constants
    //
    //--------------------------------------------------------------------------
	
	//----------------------------------
	//  ARM_KEY
	//----------------------------------
	/**
	 * Sets the key for the hero to arm itself
	 */
	public static const ARM_KEY:String = "ONE";

    //----------------------------------
    //  TOP
    //----------------------------------
    /**
     * @private
     */
    private static const TOP:String = "top";

    //----------------------------------
    //  BOTTOM
    //----------------------------------
    /**
     * @private
     */
    private static const BOTTOM:String = "bottom";	

    //----------------------------------
    //  MIDDLE
    //----------------------------------
    /**
     * @private
     */
    private static const MIDDLE:String = "middle";
	
    // --------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Creates a new instance of this class.
     */
    public function DonquiCocoGame()
    {
		bgColor = 0xFFDEDEDE;
		super();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    //----------------------------------
    //  controller
    //----------------------------------
    /**
     *  @private
     */
    private var controller:Controller;
    
    //----------------------------------
    //  mario
    //----------------------------------
    /**
     *  @private
     */
    private var mario:Mario;
	
    //----------------------------------
    //  donki
    //----------------------------------
    /**
     *  @private
     */
    private var donki:Donki;
	

	//----------------------------------
	//  spawnTimer
	//----------------------------------
	/**
	 *  @private
	 */
	private var spawnTimer:Number = 1;	
	
	
    //----------------------------------
    //  enemies
    //----------------------------------
    /**
     *  @private
     */
    private var enemies:FlxGroup;
	
    //----------------------------------
    //  floorMap
    //----------------------------------
    /**
     *  @private
     */
    private var floorMap:FlxTilemap;
	
	//----------------------------------
	//  laddersMap
	//----------------------------------
	/**
	 *  @private
	 */
	private var ladderMap:FlxTilemap;
    
    //----------------------------------
    //  floorTileSide
    //----------------------------------
    /**
     *  @private
     */
    private var floorTileSide:int = 32;
	
	
	//----------------------------------
	//  Font
	//----------------------------------
	/**
	 *  @private
	 */
	[Embed(source="assets/SFSlapstickComic.ttf", fontFamily="SFSlapstickComic", embedAsCFF="false")]
	private var myfont:String;
	
    

    //----------------------------------
    //  ladderTileSide
    //----------------------------------
    /**
     *  @private
     */
    private var ladderTileSide:int = 16;
	

	
	//----------------------------------
	//  liveScore
	//----------------------------------
	/**
	 *  @private
	 */
	private var liveScore:FlxText;	


    //----------------------------------
    //  highScore
    //----------------------------------
    /**
     *  @private
     */
    private var highScoreText:FlxText;	
	
	//----------------------------------
	//  remainingLives
	//----------------------------------
	/**
	 *  @private
	 */
	private var remainingLives: FlxText;
	
	//----------------------------------
	//  gameOver
	//----------------------------------
	private var gameOverText: FlxText;

	
    //----------------------------------
    //  isJumping
    //----------------------------------
    /**
     *  @private
     */
    private var isJumping:Boolean;

    //----------------------------------
    //  jumpStartingPoint
    //----------------------------------
    /**
     *  @private
     */
    private var jumpStartingPoint:FlxPoint;

    //----------------------------------
    //  jumpLength
    //----------------------------------
    /**
     *  @private
     */
    private var jumpLength:uint = 50;

    //----------------------------------
    //  jumpHeigh
    //----------------------------------
    /**
     *  @private
     */
    private var jumpHeight:uint = 50;

    //----------------------------------
    //  jumpVelocity
    //----------------------------------
    /**
     *  @private
     */
    private var jumpVelocity:Number = Math.PI / 25;

    //----------------------------------
    //  angle
    //----------------------------------
    /**
     *  @private
     */
    private var angle:Number;
	


    //--------------------------------------------------------------------------
    //
    //  Overridden Methods - FlxState
    //
    //--------------------------------------------------------------------------

    override public function create():void
    {
        super.create();
		var bg:FlxSprite = new FlxSprite(0,0, Skins.BACKGROUND);
		//bg.alpha = 0.7;
		add(bg);
		
		//Load an embedded sound and fade it in over 1 second
		
		
		
		//FlxG.music(Sounds.SOUND_LOOP);

		
        floorMap = new FlxTilemap();
        floorMap.drawIndex = 0;
        floorMap.loadMap(
            new Maps.MAP_DATA(), 
            Skins.MAP_TILES, 
            floorTileSide, 
            floorTileSide
            );
        floorMap.render();
        add(floorMap);

		ladderMap = new FlxTilemap();
		ladderMap.drawIndex = 0;
		ladderMap.collideIndex = 2;
		ladderMap.loadMap(
            new Maps.LADDER_DATA(), 
            Skins.LADDER_TILES, 
            ladderTileSide, 
            ladderTileSide
        );
		ladderMap.render();
		add(ladderMap);
		
		donki = new Donki();
		donki.x = 50;
		donki.y = 80;
		add(donki);

		donki.hitFloorLeftRight();
		
		enemies = new FlxGroup();
		add(enemies);
		
		highScoreText = new FlxText(10, 4, 400, "High Score = 60,000,000");
		highScoreText.setFormat("SFSlapstickComic", 16, 0xFFfec210, "left", 5); 
		add(highScoreText);
		
		FlxG.score = 0;
		liveScore = new FlxText (10, 26, 200, "Your Score is = 0");
		liveScore.setFormat("SFSlapstickComic", 13, 0xFF00b2e2, "left", 5); 
		add(liveScore);
		
		remainingLives = new FlxText(350, 4,120, "2 Lives Remaining");
		remainingLives.setFormat("SFSlapstickComic", 14, 0xFF7dbf10, "right", 5);
		add(remainingLives);

		mario = new Mario();
        mario.x = 64;
        mario.y = 570;
        add(mario);

		var joyStick:FlxSprite = new FlxSprite(0, 0, Skins.JOYSTICK);
		joyStick.y = FlxG.height - joyStick.height;
		add(joyStick);

        controller = new Controller(true);
        addChild(controller);
	}
    
    override public function update():void
	{
        var downLadderTile:LadderTile = LadderTile.TILE_LIST[getTile(mario, ladderMap)];
        var upLadderTile:LadderTile = LadderTile.TILE_LIST[getTile(mario, ladderMap, MIDDLE)];
        var floorTile:FloorTile = FloorTile.TILE_LIST[getTile(mario, floorMap)];
        var jumpDirection:int = 1;
        
        if (!mario.dead)
        {
            if (floorTile && !isJumping && FlxG.keys.justPressed("SPACE"))
            {
                isJumping = true;
                angle = Math.PI;
                if (mario.direction == FlxSprite.LEFT)
                    angle = Math.PI * 2;

                jumpStartingPoint = new FlxPoint(mario.x, mario.y);
                mario.jump();
            }
            else if (floorTile && FlxG.keys.LEFT)
            {
                mario.moveLeft();
                updateY(mario, floorTile);
            }
            else if (floorTile && FlxG.keys.RIGHT)
            {
                mario.moveRight();
                updateY(mario, floorTile);
            }
            else if (upLadderTile && FlxG.keys.UP)
            {
                mario.moveUp();
            }
            else if (downLadderTile && FlxG.keys.DOWN)
            {
                mario.moveDown();
            }
            else if (floorTile)
            {
                mario.stopMoving();
                updateY(mario, floorTile);
            }

            else if (upLadderTile || downLadderTile && !isJumping)
            {
                mario.pauseOnLadder();
            }

            else if (!isJumping)
            {
                mario.fall();
			}
            
            // barrel
    		if(spawnTimer < 0)
    			spawnEnemy();
    		else
    			spawnTimer-=FlxG.elapsed;
    		
            // collisions
            FlxU.overlap(mario, enemies, overlapMarioEnemies);
			FlxU.overlap(enemies, mario, overlapMarioEnemies);
            
            // jumping
            if (isJumping)
            {
                if (Math.PI <= angle && angle <= (Math.PI * 2))
                {
                    if (mario.direction == FlxSprite.RIGHT)
                        jumpRight();
                    else if (mario.direction == FlxSprite.LEFT)
                        jumpLeft();
                    else
                        jumpOnTheSpot();
                }
                else
                {
                    isJumping = false;
                    mario.fall();
			
					
                }
            }
        }
		
		if(FlxG.keys.ENTER && mario.dead)
			
		{
			
			FlxG.state = new DonquiCocoGame();
			
		}
        for (var i:int = 0; i < enemies.members.length; i++)
            updateBarrel(enemies.members[i])
        
        super.update();
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  jumpRight
    //----------------------------------
    /**
     * @private
     */
    private function jumpRight():void
    {
        var jumpPoint:FlxPoint = new FlxPoint
        (
            Math.cos(angle) * (jumpLength / 2),
            Math.sin(angle) * jumpHeight
        );
        mario.x = jumpPoint.x + jumpStartingPoint.x + (jumpLength / 2);
        mario.y = jumpPoint.y + jumpStartingPoint.y;

        angle += jumpVelocity;        
    } 

    //----------------------------------
    //  jumpLeft
    //----------------------------------
    /**
     * @private
     */
    private function jumpLeft():void
    {
        var jumpPoint:FlxPoint = new FlxPoint
        (
            Math.cos(angle) * (jumpLength / 2),
            Math.sin(angle) * jumpHeight
        );
        
        mario.x = jumpPoint.x + jumpStartingPoint.x - mario.width;
        mario.y = jumpPoint.y + jumpStartingPoint.y;
        
        angle -= jumpVelocity;
    } 	

    //----------------------------------
    //  jumpOnTheSpot
    //----------------------------------
    /**
     * @private
     */
    private function jumpOnTheSpot():void
    {
        mario.y = (Math.sin(angle) * jumpHeight) + jumpStartingPoint.y;
        angle += jumpVelocity;        
    } 

    //----------------------------------
    //  spawnEnemy
    //----------------------------------
    /**
     * @private
     */
    private function spawnEnemy():void
    {
		var barrel:Barrel = new Barrel();
        barrel.x = 140;
		barrel.y = 0;
		enemies.add(barrel);
		spawnTimer = Utils.randRange(3, 6);
    } 	

    //----------------------------------
    //  updateBarrel
    //----------------------------------
    /**
     * @private
     */
    private function updateBarrel(barrel:Barrel):void
    {
        var floorTile:FloorTile = 
            FloorTile.TILE_LIST[getTile(barrel, floorMap)];
        
        if (mario.dead)
        {
            barrel.stopMoving();
			gameOverText = new FlxText(0, 350, FlxG.width,"Game Over\nPress enter\nto restart");
			gameOverText.setFormat("SFSlapstickComic", 34, 0xFFb62424, "center",20);
			add(gameOverText);
			
        }
        else if (floorTile)
        {
            updateY(barrel, floorTile);
            if (barrel.lastDirection == -1)
                barrel.moveRight();
            else if (barrel.lastDirection == FlxSprite.LEFT)
                barrel.moveRight();
            else 
                barrel.moveLeft();
        }
        else
        {
            barrel.fall();
        }
    } 	
    
	//----------------------------------
    //  updateMarioY
    //----------------------------------
    /**
     * @private
     */
    private function updateY(sprite:FlxSprite, tile:FloorTile):void
    {
        var tileX:int = 
            Math.floor((sprite.x + sprite.origin.x) / floorTileSide);
        var tileY:int = 
            Math.floor((sprite.y + sprite.height + 3) / floorTileSide);
        var tile:FloorTile = 
            FloorTile.TILE_LIST[floorMap.getTile(tileX, tileY)];
            
        sprite.y = 
            tileY  * floorTileSide - sprite.height + tile.depth;
    } 

    //----------------------------------
    //  getUpdatedTile
    //----------------------------------
    /**
     * @private
     */
    private function getTile(sprite:FlxSprite, map:FlxTilemap, 
                                           position:String=BOTTOM):int
    {
        var side:int;
        
        switch (map)
        {
            case (floorMap):
            {
                side = floorTileSide;
                break;
            }
            case (ladderMap):
            {
                side = ladderTileSide;
                break;
            }
            default:
            {
                side = 32;
            }
                
        }
        
        var point:FlxPoint = new FlxPoint();
        point.x = Math.floor((sprite.x + sprite.origin.x) / side);
        
        switch (position)
        {
            case (BOTTOM):
            {
                point.y = Math.floor((sprite.y + sprite.height + 3) / side);
                break;
            }
            case (MIDDLE):
            {
                point.y = Math.floor((sprite.y + sprite.origin.y) / side);
                break;
            }
            case (TOP):
            {
                point.y = Math.floor((sprite.y) / side);
                break;
            }
        }
        
        return map.getTile(point.x, point.y);
    } 

    //--------------------------------------------------------------------------
    //
    //  Overlap callbacks
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  overlapMarioEnemies
    //----------------------------------
    /**
     * @private
     */
    private function overlapMarioEnemies(mario:FlxSprite, enemy:FlxSprite):void
    {
        mario.kill();
		enemies.kill();
		add(gameOverText);
    } 
	

}
}
